package com.foolishbird.sdk.ui.activity;

import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;


import com.foolishbird.sdk.assist.AlipayPayOperation;
import com.foolishbird.sdk.assist.CallbackObservable;
import com.foolishbird.sdk.assist.Constant;
import com.foolishbird.sdk.core.HttpEngineApi;
import com.foolishbird.sdk.handler.SimpleAsyncResponseHandler;
import com.foolishbird.sdk.params.CreateOrderResponseParams;
import com.foolishbird.sdk.params.PayChannelResponseParams;
import com.foolishbird.sdk.params.ResponseParams;
import com.foolishbird.sdk.params.bean.Goods;
import com.foolishbird.sdk.params.bean.PayChannel;
import com.foolishbird.sdk.params.bean.PayChannelInfo;
import com.foolishbird.sdk.params.bean.PayType;
import com.foolishbird.sdk.params.bean.State;
import com.foolishbird.sdk.ui.assist.PayChannelListAdapter;
import com.foolishbird.sdk.ui.view.DialogFactory;
import com.foolishbird.sdk.utils.ToolsUtils;
import com.unionpay.UPPayAssistEx;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;



public class FoolishBirdPaymentActivity extends AppBaseActivity implements AdapterView.OnItemClickListener, View.OnClickListener {

    private static final String TAG = FoolishBirdPaymentActivity.class.getSimpleName();
    private static final int REQUEST_CODE = 0x0000;
    private static final int APPLET_REQUEST_CODE = 0x0001;
    private static final int START_DEFAULT_BROWSER_REQUEST_CODE = 0x0003;
    private static final String UNION_PAY_MODE = "00";
    private static final String UNION_PAY_RESULT = "pay_result";

    private final CopyOnWriteArrayList<PayChannel> mDefaultShowChannels = new CopyOnWriteArrayList<>();
    private final CopyOnWriteArrayList<PayChannel> mDefaultHideChannels = new CopyOnWriteArrayList<>();

    private TextView mGoodsPriceTv;

    private Button mGoodsSubmitBtn;
    private ListView mPaymentChannelsLv;
//    private View mShowMorePayChannelView;

    private Goods mGoods;
    private int mGetPayChannelTaskId;
    private int mCreateOrderTaskId;
    private PayChannelListAdapter mAdapter;
    private View lastSelectedView;
    private int lastSelectedPosition;

    private float mPriceRatio = 1f;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        onInitData();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        HttpEngineApi.getInstance().cancel(mCreateOrderTaskId);
    }

    private void onInitViews() {
        setContentView(getLayoutIdentifier("foolishbird_activity_payment"));
        mGoodsPriceTv = findViewById(getViewIdentifier("hnssn_activity_payment_goods_price"));
        findViewById(getViewIdentifier("fb_fragment_login_close")).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finishPaymentActivity(view);
            }
        });
        TextView title = findViewById(getViewIdentifier("fb_fragment_notice_title"));
        title.setText("订单支付");
        findViewById(getViewIdentifier("fb_fragment_login_close")).setVisibility(View.GONE);
        ImageView closeImage = findViewById(getViewIdentifier("fb_fragment_login_close"));
        closeImage.setVisibility(View.VISIBLE);
        closeImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finishPaymentActivity(view);
            }
        });
        mGoodsSubmitBtn = findViewById(getViewIdentifier("activity_payment_confirm"));
        mPaymentChannelsLv = findViewById(getViewIdentifier("hnssn_activity_payment_type_lv"));
//        mShowMorePayChannelView = findViewById(getViewIdentifier("hnssn_activity_payment_more"));
        mPaymentChannelsLv.setOnItemClickListener(this);
        mGoodsSubmitBtn.setOnClickListener(this);
        findViewById(getViewIdentifier("activity_payment_question")).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(FoolishBirdPaymentActivity.this, FoolishBirdFloatExtensionActivity.class);

                intent.putExtra("custom",true);
                startActivity(intent);
                finish();
            }
        });
    }

    private void onInitData() {
        Intent intent = getIntent();
        if (intent != null) {
            mGoods = intent.getParcelableExtra("goods");
            if (mGoods != null) {
                getPayChannel(mGoods);
            }
        }
    }

    private void generateDefaultDisplayChannels(List<PayChannel> source, List<PayChannel> show, List<PayChannel> hide) {
        if (source != null & !source.isEmpty()) {
            for (PayChannel channel : source) {
                if (channel != null) {
                    if (channel.isHidden()) {
                        hide.add(channel);
                    } else {
                        show.add(channel);
                    }
                }
            }
        }
    }

    @Override
    public void onBackPressed() {
        if (!isForbidBackSuper()) {
            CallbackObservable observable = CallbackObservable.getInstance();
            String message = getString(getStringIdentifier("hnssn_h5payhint_cancel"));
            observable.callResponseResult(Constant.CallType.CALL_PAY, Constant.PayState.PAY_CANCEL, message, null);
            super.onBackPressed();
        }
    }

    public void finishPaymentActivity(View view) {
        CallbackObservable observable = CallbackObservable.getInstance();
        String message = getString(getStringIdentifier("hnssn_h5payhint_cancel"));
        observable.callResponseResult(Constant.CallType.CALL_PAY, Constant.PayState.PAY_CANCEL, message, null);
        finish();
    }

    public void showMorePayChannel(View view) {
        List<PayChannel> channels = (List<PayChannel>) mDefaultShowChannels.clone();
        channels.addAll(mDefaultHideChannels);
        mAdapter.setAdapterData(channels);
        mAdapter.notifyDataSetChanged();
//        mShowMorePayChannelView.setVisibility(View.GONE);
    }

    private void payByWeixin(PayType type) {
//        createOrder(type.getStartIndex(), mGoods);
        if (ToolsUtils.isInstallWeixin(this)) {
            createOrder(type.getStartIndex(), mGoods);
        } else {
            DialogFactory.createConfirmDialog(this, getString(getStringIdentifier("hnssn_hint_wxpay"))).show();
        }
    }

    private void payByUnionAppPay(PayType type) {
        if (ToolsUtils.isInstallUnionPay(this)) {
            createOrder(type.getStartIndex(), mGoods);
        } else {
            DialogFactory.createConfirmDialog(this, getString(getStringIdentifier("hnssn_hint_union_app"))).show();
        }
    }

    private void getPayChannel(Goods goods) {
        SimpleAsyncResponseHandler handler = requestCallbackHandler(PayChannelResponseParams.class);
        mGetPayChannelTaskId = HttpEngineApi.getInstance().getPayChannelInfo(goods, handler);
    }

    private void createOrder(int type, Goods goods) {
        SimpleAsyncResponseHandler handler = requestCallbackHandler(CreateOrderResponseParams.class, PayType.valueOf(type));
        mCreateOrderTaskId = HttpEngineApi.getInstance().createOrder(type, goods, handler);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
            CallbackObservable observable = CallbackObservable.getInstance();
            String message = getString(getStringIdentifier("hnssn_h5payhint_success"));
            observable.callResponseResult(Constant.CallType.CALL_PAY, Constant.PayState.PAY_SUCCESS, message, null);
        } else if (START_DEFAULT_BROWSER_REQUEST_CODE == requestCode) {
            CallbackObservable observable = CallbackObservable.getInstance();
            String message = getString(getStringIdentifier("hnssn_h5payhint_unknown"));
            observable.callResponseResult(Constant.CallType.CALL_PAY, Constant.PayState.PAY_UNKNOWN, message, null);
        } else if (APPLET_REQUEST_CODE == requestCode) {
            if (RESULT_CANCELED == resultCode) {
                CallbackObservable observable = CallbackObservable.getInstance();
                String message = getString(getStringIdentifier("hnssn_h5payhint_unknown"));
                observable.callResponseResult(Constant.CallType.CALL_PAY, Constant.PayState.PAY_UNKNOWN, message, null);
            }
        }
//        else if (HeepayPayOperation.RESULT_CODE == resultCode) {
//            HeepayPayOperation.onActivityResult(requestCode, resultCode, data);
//        }
        else {
            //云闪付支付回调通知检测
            if (data != null && data.hasExtra(UNION_PAY_RESULT)) {
                String unionPayResult = data.getStringExtra(UNION_PAY_RESULT);
                if ("success".equalsIgnoreCase(unionPayResult)) {
                    CallbackObservable observable = CallbackObservable.getInstance();
                    String message = getString(getStringIdentifier("hnssn_h5payhint_success"));
                    observable.callResponseResult(Constant.CallType.CALL_PAY, Constant.PayState.PAY_SUCCESS, message, null);
                } else if ("cancel".equalsIgnoreCase(unionPayResult)) {
                    CallbackObservable observable = CallbackObservable.getInstance();
                    String message = getString(getStringIdentifier("hnssn_h5payhint_cancel"));
                    observable.callResponseResult(Constant.CallType.CALL_PAY, Constant.PayState.PAY_CANCEL, message, null);
                } else {
                    CallbackObservable observable = CallbackObservable.getInstance();
                    String message = getString(getStringIdentifier("hnssn_h5payhint_faile"));
                    observable.callResponseResult(Constant.CallType.CALL_PAY, Constant.PayState.PAY_FAILED, message, null);
                }
            } else {
                CallbackObservable observable = CallbackObservable.getInstance();
                String message = getString(getStringIdentifier("hnssn_h5payhint_cancel"));
                observable.callResponseResult(Constant.CallType.CALL_PAY, Constant.PayState.PAY_CANCEL, message, null);
            }
        }
        finish();
    }

    @Override
    public void onAsyncRequestResult(int flag, ResponseParams response, Object... params) {
        super.onAsyncRequestResult(flag, response, params);
        if (flag == mCreateOrderTaskId) {
            executeCreateOrderResult(response, (PayType) params[0]);
        } else if (flag == mGetPayChannelTaskId) {
            executePayChannelResult(response);
        }
    }

    private void initOrderPriceInfo(PayChannel channel, float ratio) {
        if (channel != null) {
            final BigDecimal discountPrice;
            final BigDecimal goodsPrice = channel.getCurrencyPrice();
            if (ratio != 1f) {
                discountPrice = goodsPrice.multiply(new BigDecimal(ratio));
                int resId = getStringIdentifier("hnssn_h5payhint_goods_discount_price");

            } else {
                discountPrice = goodsPrice;

            }

            String currencySymbol = channel.getCurrency();
            mGoodsPriceTv.setText(getString(getStringIdentifier("hnssn_h5payhint_goods_price"),  goodsPrice.floatValue()/100));
//            mGoodsSubmitBtn.setText(getString(getStringIdentifier("hnssn_pay_table_submit_text"), currencySymbol, discountPrice.floatValue()));
        }
    }

    private void executePayChannelResult(ResponseParams response) {
        if (response instanceof PayChannelResponseParams) {
            PayChannelResponseParams responseParams = (PayChannelResponseParams) response;
            if (responseParams.isSuccess()) {
                onInitViews();

                PayChannelInfo payChannelInfo = responseParams.getData();
                if (payChannelInfo != null) {
//                    mPriceRatio = payChannelInfo.getDiscount();
                    List<PayChannel> channels = payChannelInfo.getPayChannel();
                    if (!channels.isEmpty()) {
                        initOrderPriceInfo(channels.get(0), mPriceRatio);
                    }

                    generateDefaultDisplayChannels(channels, mDefaultShowChannels, mDefaultHideChannels);

                    mAdapter = new PayChannelListAdapter();
                    mAdapter.setAdapterData(mDefaultShowChannels);
                    mPaymentChannelsLv.setAdapter(mAdapter);

//                    if (mDefaultHideChannels.isEmpty()) {
//                        mShowMorePayChannelView.setVisibility(View.GONE);
//                    } else {
//                        mShowMorePayChannelView.setVisibility(View.VISIBLE);
//                    }
                } else {
                    Toast.makeText(this,responseParams.getState().getMsg(),Toast.LENGTH_SHORT).show();
                    finishPaymentActivity(null);
                }
            } else {
                Toast.makeText(this,responseParams.getState().getMsg(),Toast.LENGTH_SHORT).show();
                finishPaymentActivity(null);
            }
        }

    }

    private void executeCreateOrderResult(ResponseParams response, PayType payType) {
        if (response instanceof CreateOrderResponseParams) {
            CreateOrderResponseParams responseParams = (CreateOrderResponseParams) response;
            if (State.SUCCESS == responseParams.getState().getCode()) {
                int type = Integer.valueOf(responseParams.getData().getType());
                switch (type){
                    case 1:
                        startDefaultWebBrowser(responseParams.getData());
                        break;
                    case 2:
                        weixinPay(responseParams.getData());
                        break;
                    case 3:
                        alipayPayV1(responseParams.getData());
                        break;
                    case 4:
                    default:
                        startDefaultWebBrowser(responseParams.getData());
                        break;

                }
//                switch (payType) {
//                    case WEIXIN_PAY:
//                        weixinPay(responseParams.getData());
//                        break;
//
//                    case ALIPAY_PAY:
//                        alipayPayV1(responseParams.getData());
//                        break;
//
//                    case UNION_PAY:
//                        webH5Pay(responseParams.getData());
//                        break;
//                    case DEFAULT_WEB_BROWSER:
//                        startDefaultWebBrowser(responseParams.getData());
//                        break;
//                    default:
//                        DialogFactory.createConfirmDialog(this, getString(getStringIdentifier("hnssn_hint_payerror"))).show();
//                }
            }
        }
    }

    private void doStartUnionPayPlugin(CreateOrderResponseParams.CreateOrderResponseData response) {
        if (response != null) {
            UPPayAssistEx.startPay(this, null, null, response.getPay_info(), UNION_PAY_MODE);
        }
    }

    private void weixinPay(CreateOrderResponseParams.CreateOrderResponseData response) {
        if (response != null) {
            int type = 0;
            if (ToolsUtils.checkNumber(response.getType())) {
                type = Integer.parseInt(response.getType());
            }
            webH5Pay(response);
//            switch (type) {
//                case 2:
//                    HeepayPayOperation.pay(this, response.getPay_info(), response.getOrder_no());
//                    break;
//                default:
//                    webH5Pay(response);
//            }
        }
    }

    private void weixinAppletPay(CreateOrderResponseParams.CreateOrderResponseData response) {
        if (response != null) {
            Intent intent = new Intent(Constant.LocalIntentAction.INTENT_AACTION_WECHAT_APPLET_PAY);
            intent.setPackage(getPackageName());
            intent.putExtra("wechat_applet_pay_info", response.getPay_info());
            startActivityForResult(intent, APPLET_REQUEST_CODE);
        }
    }

    private void alipayPayV1(final CreateOrderResponseParams.CreateOrderResponseData response) {
        if (response != null) {
            new AlipayPayOperation(this).execute(response.getPay_info());
        }
    }

    private void webH5Pay(final CreateOrderResponseParams.CreateOrderResponseData response) {
        Intent intent = new Intent(this, WXH5PayActivity.class);
        intent.setPackage(getPackageName());

        intent.putExtra("weixinPay", response);
        startActivityForResult(intent, REQUEST_CODE);
    }

    private void startDefaultWebBrowser(final CreateOrderResponseParams.CreateOrderResponseData response) {
        String url = response != null ? response.getPay_info() : "";
        if (!TextUtils.isEmpty(url)) {
            try {
                startActivityForResult(new Intent(Intent.ACTION_VIEW, Uri.parse(url)), START_DEFAULT_BROWSER_REQUEST_CODE);
            } catch (ActivityNotFoundException exception) {
                final int resId = getStringIdentifier("hnssn_h5payhint_webclient_excepition");
                Toast.makeText(getApplicationContext(), resId, Toast.LENGTH_SHORT).show();

                CallbackObservable observable = CallbackObservable.getInstance();
                String message = getString(getStringIdentifier("hnssn_h5payhint_cancel"));
                observable.callResponseResult(Constant.CallType.CALL_PAY, Constant.PayState.PAY_CANCEL, message, null);
            }
        } else {
            CallbackObservable observable = CallbackObservable.getInstance();
            String message = getString(getStringIdentifier("hnssn_h5payhint_cancel"));
            observable.callResponseResult(Constant.CallType.CALL_PAY, Constant.PayState.PAY_CANCEL, message, null);
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        if (lastSelectedView == null) {
            View firstView = parent.getChildAt(parent.getFirstVisiblePosition());
            resetItemViewSelectedState(firstView, false);
        }

        if (lastSelectedView != view) {
            resetItemViewSelectedState(lastSelectedView, false);
            resetItemViewSelectedState(view, true);
            this.lastSelectedView = view;
            this.lastSelectedPosition = position;
            mAdapter.setLastSelectedIndex(position);
        }

        initOrderPriceInfo(mAdapter.getItem(position), mPriceRatio);
    }

    private void resetItemViewSelectedState(View view, boolean selected) {
        if (view != null) {
            Object obj = view.getTag();
            if (obj instanceof PayChannelListAdapter.ViewHolder) {
                PayChannelListAdapter.ViewHolder viewHolder = (PayChannelListAdapter.ViewHolder) obj;
                viewHolder.checked.setChecked(selected);
            }
        }
    }

    @Override
    public void onClick(View view) {
        PayChannel channel = mAdapter.getItem(lastSelectedPosition);
        PayType type = channel.getPayTypeEnum();
        switch (type) {
            case WEIXIN_PAY:
//            case WEIXIN_APPLET_PAY:
                payByWeixin(type);
                break;
//            case UNION_APP_PAY:
//                payByUnionAppPay(type);
//                break;
            default:
                createOrder(channel.getPayType(), mGoods);
        }

    }
}
